package com.gc.services.impl;

import com.gc.common.constants.SysConstants;
import com.gc.common.util.MyUtil;
import com.gc.common.util.QrCodeUtils;
import com.gc.dao.custom.ClientMapper;
import com.gc.dao.custom.ReportMapper;
import com.gc.dto.ClientDTO;
import com.gc.dto.ReportDTO;
import com.gc.dto.VorDTO;
import com.gc.pojo.*;
import com.gc.services.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ReportServiceImpl implements ReportService {
    @Autowired
    private ReportMapper reportMapper;
    @Autowired
    private ClientService clientService;
    @Autowired
    private DeviceService deviceService;
    @Autowired
    private UserService userService;
    @Autowired
    private VorService vorService;
    @Autowired
    private EntrustService entrustService;
    @Autowired
    private ClientMapper clientMapper;


    @Override
    public List<ReportDTO> getMyReportList(Integer uid) {
        return wtdwTrans(reportMapper.selectByUId(uid));
    }

    @Override
    public List<ReportDTO> getAllReportList() {
        return wtdwTrans(reportMapper.selectAll());
    }

    @Override
    public int addReport(SysReport report) {
        return reportMapper.insertSelective(report);
    }

    @Override
    public int modifyShyByRid(Integer rid, Integer shyId) {
        return reportMapper.updateCheckByRid(rid,shyId);
    }

    @Override
    public int modifyStatusByRid(Integer rid, int status) {
        return reportMapper.updateStatusByRid(rid,status);
    }


    @Override
    public int checkPassReportByRid(Integer rid, int status) {
        SysUser curUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
        SysReport report = new SysReport();
        report.setReportId(rid);
        report.setCheckBy(curUser.getUserId());
        report.setCheckTime(new Date());
        report.setStatus(status);
        return reportMapper.updateByPrimaryKeySelective(report);
    }

    @Override
    public int checkRejectReportByRid(Integer rid, String msg, int status) {
        SysUser curUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
        SysReport report = new SysReport();
        report.setReportId(rid);
        report.setCheckBy(curUser.getUserId());
        report.setCheckTime(new Date());
        report.setStatus(status);
        report.setCheckRemark(msg);
        return reportMapper.updateByPrimaryKeySelective(report);
    }

    @Override
    @Transactional
    public boolean signPassReportByRid(Integer rid, int status) {
        try {
            SysUser curUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
            SysReport report = new SysReport();
            report.setReportId(rid);
            report.setSignBy(curUser.getUserId());
            report.setSignTime(new Date());
            report.setStatus(status);
            int count1 = reportMapper.updateByPrimaryKeySelective(report);
            if(count1 != 1){
                log.error("107:签发时,更新报告状态出错!");
                throw new Exception();
            }
            //如果缓慢的话 , 可开启线程 , 或者 消息队列
            SysReport report2 = this.getReportByRid(rid);
            SysVor vor = vorService.getVorByVid(report2.getVorId());
            //生成报告编号
            StringBuffer bgbh = vorService.generatorReportNumber(vor);
            //修改报告编号
            int count2 = vorService.modifyReportNumber(vor.getVorId(), bgbh.toString());
            if(count2 != 1){
                log.error("118:签发时,更新报告编号出错!");
                throw new Exception();
            }
            int count3 = this.modifyReportNumber(report2.getReportId(), bgbh.toString());
            if (count3 != 1) {
                log.error("123:签发时,更新报告编号出错!");
                throw new Exception();
            }
            //生成委托记录
            SysEntrust entrust = vorService.generatorEntrustRecord(vor);
            int count4 = entrustService.addEntrust(entrust);  //插入
            if (count4 != 1) {
                log.error("130:签发时,添加委托记录失败!");
                throw new Exception();
            }
            //生成设备使用记录
            SysDeviceUse use = vorService.generatorDeviceRecord(vor);
            int count5 = deviceService.addDeviceUse(use);   //插入
            if (count5 != 1) {
                log.error("137:签发时,添加设备使用记录失败!");
                throw new Exception();
            }
            QrCodeUtils.encode(SysConstants.QRCODE_URL+report2.getVorId(),"","D:/images/",bgbh+".png",false);
        } catch (Exception e) {
            log.error("------报告签发失败!-------");
            e.printStackTrace();
            return  false;
        }
        return true;
    }

    @Override
    public int signRejectReportByRid(Integer rid, String msg, int status) {
        SysUser curUser = (SysUser) SecurityUtils.getSubject().getPrincipal();
        SysReport report = new SysReport();
        report.setReportId(rid);
        report.setSignBy(curUser.getUserId());
        report.setSignTime(new Date());
        report.setStatus(status);
        report.setCheckRemark(msg);
        return reportMapper.updateByPrimaryKeySelective(report);
    }

    @Override
    public List<ReportDTO> getCheckReportList() {
        return wtdwTrans(reportMapper.selectCheckReport());
    }

    @Override
    public List<ReportDTO> getPrintReportList() {
        return wtdwTrans(reportMapper.selectPrintReport());
    }


    @Override
    public SysReport getReportByRid(Integer rid) {
        return reportMapper.selectByPrimaryKey(rid);
    }

    @Override
    public int modifyReportNumber(Integer rid,String bgbh) {
        return reportMapper.updateReportNumber(rid,bgbh);
    }

    @Override
    public SysReport getReportByVid(Integer vid) {
        return reportMapper.selectByVid(vid);
    }

    @Override
    public int modifyReport(SysReport report) {
        return reportMapper.updateByPrimaryKey(report);
    }

    @Override
    public List<ReportDTO> getMyReportListByCid(Integer uid, Integer cid) {
        return reportMapper.selectByUidAndCid(uid,cid);
    }




    private List<ReportDTO> wtdwTrans(List<ReportDTO> list){
        Map<Integer, String> clientMap = clientMapper.selectAllClient().stream()
                .collect(Collectors.toMap(SysClient::getClientId, SysClient::getClientName, (k1, k2) -> k2));
        list.forEach((reportDTO) -> {
            try {
                reportDTO.setClientName(clientMap.get(Integer.valueOf(reportDTO.getClientId())));
            } catch (NumberFormatException e) {
                log.error(reportDTO.getClientName() + ",转换Integer失败!");
            }
        });
        return list;
    }
}